package by.jtraining.london.repo.Impl;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import by.jtraining.london.repo.GenericRepository;

import com.google.common.base.Preconditions;
import com.google.inject.persist.Transactional;

public abstract class GenericRepositoryImpl<E, ID extends Serializable>
		implements GenericRepository<E, ID> {

	private static final Logger LOG = LoggerFactory
			.getLogger(GenericRepositoryImpl.class);

	protected final EntityManager em;
	protected final Class<E> persistentClass;

	public GenericRepositoryImpl(EntityManager entityManager,
			Class<E> persistentClass) {
		this.em = Preconditions.checkNotNull(entityManager);
		this.persistentClass = Preconditions.checkNotNull(persistentClass);
	}

	@Transactional
	public List<E> findAll() {
		LOG.debug("Trying to find all persisted objects of {}",
				persistentClass.getSimpleName());
		TypedQuery<E> query = em.createQuery("SELECT object(o) FROM "
				+ persistentClass.getSimpleName() + " AS o", persistentClass);

		List<E> entities = query.getResultList();

		LOG.debug("{} object(s) found.", entities.size());

		return entities;
	}

	@Transactional
	public E getById(ID id) {
	    LOG.debug("Trying to find {} with ID #{}", persistentClass.getSimpleName(), id);
	    E found=em.find(persistentClass, id);
	    LOG.debug("Found {}", found);
	    return found;
		
	}

	@Transactional
	public void save(E entity) {
		LOG.debug("Trying to update {}", entity);
		em.merge(entity);
	}

}
